<?php

require_once( 'flexical/model/object.php' );
require_once( 'flexical/model/feed.php' );
require_once( 'flexical/model/query.php' );
require_once( 'flexical/model/format.php' );
require_once( 'flexical/model/listing.php' );

require_once( 'flexical/admin/view.php' );

abstract class Flexical_Admin_Basic_Listing_View extends Flexical_Admin_View
{
	public function get_selected_tab()
	{
		return $this->LISTINGS_TAB;
	}

	public function get_description( $listing, $feeds, $queries, $formats )
	{
		$desc = '';

		$desc .= 'Shortcode Key: ' . $listing->shortcode_key . "<br />\n";

		$desc .= 'Sort Order: ' . ( ( $listing->sort_order == 'ascending' ) ? 'Ascending' : 'Descending' ) . "<br />\n";

		$desc .= 'Maximum Number of Events: ' . ( ( $listing->max_number_of_events == 0 ) ? "Unlimited" : $listing->max_number_of_events ) . "<br />\n";		

		$desc .= 'Format: ' . ( array_key_exists( $listing->format_id, $formats ) ? $formats[ $listing->format_id ]->title : 'None' ) . "<br />\n";

		if ( sizeof( $listing->feed_query_list ) > 0 )
		{
			$desc .= "Feeds/Queries:<br />\n";
			$fq = array();

			foreach ( $listing->feed_query_list as $id => $feed_query )
			{
				$feed_title = array_key_exists( $feed_query->feed_id, $feeds ) ? $feeds[ $feed_query->feed_id ]->title : 'None';
				$query_title = array_key_exists( $feed_query->query_id, $queries) ? $queries[ $feed_query->query_id ]->title : 'None';
				$fq[] = $feed_title . ': ' . $query_title;
			}

			$desc .= "<ul><li>\n" . implode( "</li><li>", $fq ) . "</li>\n</ul>\n";
		}

		else
		{
			$desc .= 'Feeds/Queries: None';
		}

		return $desc;
	}
}

class Flexical_Admin_Listing_View extends Flexical_Admin_Basic_Listing_View
{
	public function get_messages( $response )
	{
		$messages = array();

		switch ( get_class( $response ) )
		{
			case 'Flexical_Admin_Show_Listings_Response':
				
				if ( $response->canceled )
				{
					$messages[] = new Flexical_Admin_Info_Message( "Action canceled." );
				}

				break;

			case 'Flexical_Admin_Create_Listing_Response':
				$messages[] = new Flexical_Admin_Info_Message( "Created listing " . $response->listing->id . ": " . $response->listing->title );
				break;

			case 'Flexical_Admin_Delete_Listing_Response':
				$messages[] = new Flexical_Admin_Info_Message( "Deleted listing " . $response->listing->id . ": " . $response->listing->title );
				break;

			case 'Flexical_Admin_Update_Listing_Response':
				$messages[] = new Flexical_Admin_Info_Message( "Updated listing " . $response->listing->id . ": " . $response->listing->title );
				break;

			case 'Flexical_Admin_Test_Listing_Response':
				$messages[] = new Flexical_Admin_Info_Message( "<p>Testing listing " . $response->listing->id . ": " . $response->listing->title . ":</p>\n" .
					$response->report
				);
				break;

			case 'Flexical_Admin_Delete_All_Listings_Response':

				if ( $response->confirmed )
				{
					$messages[] = new Flexical_Admin_Info_Message( "All listings were deleted." );
				}

				else
				{
					$messages[] = new Flexical_Admin_Error_Message( "The confirmation box for that action was not checked." );
				}

				break;
		}

		return $messages;
	}

	public function render_details( $response )
	{
		echo( $this->render_listing_table( $response ) );
		echo( "<p>&nbsp;</p>" );
		$this->render_create_listing_form( $response );
		echo( "<p>&nbsp;</p>" );

		if ( sizeof( $response->listings ) > 0 )
		{
			$this->render_delete_all_listings_form();
			echo( "<p>&nbsp;</p>" );
		}
	}

	private function render_listing_table( $response )
	{
		$headings = array( 'ID', 'Title', 'Description', 'Actions' );

		$table = "<h3>Listings</h3>\n";
		$table .= "<table class=\"widefat\">";
		$table .= "<thead><tr><th>" . implode( "</th><th>", $headings ) . "</th></tr></thead>\n";

		foreach ( $response->listings as $id => $listing )
		{
			$description = $this->get_description( $listing, $response->feeds, $response->queries, $response->formats );
			$data = array( $listing->id, $listing->title, $description, $this->get_actions( $listing->id ) );
			$table .= "<tr><td align=\"left\" valign=\"top\">" . implode( "</td><td align=\"left\" valign=\"top\">", $data ) . "</td></tr>\n";
		}

		$table .= "<tfoot><tr><th>" . implode( "</th><th>", $headings ) . "</th></tr></tfoot>\n";
		$table .= "</table>\n";

		return $table;
	}

	private function get_actions( $id )
	{
		return implode( " | ", array (
			"<a href=\"" . $this->get_request_url( 'test_listing', array( 'listing_id' => $id ) ) . "\">Test</a>",
			"<a href=\"" . $this->get_request_url( 'edit_listing', array( 'listing_id' => $id ) ) . "\">Edit</a>",
			"<a href=\"" . $this->get_request_url( 'confirm_delete_listing', array( 'listing_id' => $id ) ) . "\">Delete</a>",
		) );
	}

	private function render_create_listing_form( $response )
	{
		echo( "<h3>Create a New Listing</h3>\n" );

		if ( sizeof( $response->formats ) == 0 || sizeof( $response->feeds ) == 0 || sizeof( $response->queries ) == 0 )
		{
			echo( "<p>You must create at least one feed, one query, and one format before you can create a listing.</p>" );
		}

		else
		{
			$renderer = new Flexical_Admin_Listing_Form_Renderer();
			$renderer->request_type = 'create_listing';
			$renderer->listing = null;
			$renderer->feeds = $response->feeds;
			$renderer->queries = $response->queries;
			$renderer->formats = $response->formats;
			$renderer->submit_button_text = 'Create Listing';
			$renderer->submit_enabled = true;
			$renderer->cancel_enabled = false;
			$renderer->mode = 'readwrite';
			$renderer->view = $this;

			$renderer->render();
		}
	}

	public function render_delete_all_listings_form()
	{
		echo( "<h3>Delete All Listings</h3>\n" );
		echo( "<p>This action will delete all of the listings. <b>WARNING: This action cannot be undone.</b></p>" );
		
		$info = new Flexical_Admin_Form_Table_Info();
		$info->request_type = 'delete_all_listings';
		$info->submit_button_text = 'Delete All Listings';
		$info->rows[ 'Confirm' ] = $this->get_confirmation_checkbox();
		$info->cancel_enabled = false;

		$this->render_form_table( $info );
	}
}

class Flexical_Admin_Listing_Form_Renderer
{
	public $listing;
	public $feeds;
	public $formats;
	public $queries;
	public $request_type;
	public $submit_button_text;
	public $submit_enabled;
	public $cancel_enabled;
	public $show_id_enabled;
	public $mode;

	private $max_feed_query_entries = 10;

	public function render()
	{
		$info = new Flexical_Admin_Form_Table_Info();

		if ( $this->listing == null )
		{
			$this->listing = new Flexical_Model_Listing();
		}

		else
		{
			if ( $this->show_id_enabled )
			{
				$info->rows[ 'ID' ] = $this->listing->id;
			}

			$info->hiddens[ 'listing_id' ] = $this->listing->id;
		}

		switch ( $this->mode )
		{
			case 'readonly':
				$info->rows[ 'Title' ] = $this->listing->title;
				$info->rows[ 'Description' ] = $this->view->get_description( $this->listing, $this->feeds, $this->queries, $this->formats );
				break;

			case 'readwrite':

				$formats = $this->copy_array( $this->formats );
				usort( $formats, 'Flexical_Model_Object::compare_by_title' );
				$select_format = new Flexical_Model_Format();
				$select_format->id = -1;
				$select_format->title = '- Select a Format -';
				$formats = array_merge( array( $select_format->id => $select_format ), $formats );

				$sort_orders = array(
					new Flexical_Admin_Sort_Order( 'ascending', 'Ascending' ),
					new Flexical_Admin_Sort_Order( 'descending', 'Descending' ),
				);

				$info->rows[ 'Title' ] = "<input type=\"text\" size=\"50\" name=\"listing_title\" value=\"" . $this->listing->title . "\" />\n";
				$info->rows[ 'Shortcode Key' ] = "<input type=\"text\" size=\"50\" name=\"listing_shortcode_key\" value=\"" .
					$this->listing->shortcode_key. "\" />\n";
				$info->rows[ 'Sort Order' ] = $this->get_option_list( 'listing_sort_order', $sort_orders, $this->listing->sort_order );
				$info->rows[ 'Maximum Number of Events' ] = "<input type=\"text\" size=\"10\" name=\"listing_max_number_of_events\" value=\"" . $this->listing->max_number_of_events . "\" /> &nbsp; 0 = Unlimited number of events\n";
				$info->rows[ 'Format' ] = $this->get_option_list( 'listing_format_id', $formats, $this->listing->format_id );
				$info->rows[ 'Feeds/Queries' ] = $this->get_feed_query_table( $this->max_feed_query_entries );
				$info->hiddens[ 'listing_feed_query_count' ] = $this->max_feed_query_entries;

				break;

			default:
				throw new Exception( "Unsupported form mode: " . $this->mode );
		}

		$info->submit_button_text = $this->submit_button_text;
		$info->cancel_enabled = $this->cancel_enabled;
		$info->request_type = $this->request_type;

		$this->view->render_form_table( $info );
	}

	private function get_feed_query_table( $max_feeds_queries )
	{
		$feeds = $this->copy_array( $this->feeds );
		usort( $feeds, 'Flexical_Model_Object::compare_by_title' );

		$select_feed = new Flexical_Model_Feed();
		$select_feed->id = -1;
		$select_feed->title = '- Select a Feed -';
		$feeds = array_merge( array( $select_feed->id => $select_feed), $feeds );

		$queries = $this->copy_array( $this->queries );
		usort( $queries, 'Flexical_Model_Object::compare_by_title' );

		$select_query = new Flexical_Model_Query();
		$select_query->id = -1;
		$select_query->title = '- Select a Query -';
		$queries = array_merge( array( $select_query->id => $select_query) , $queries );

		$fq_list = array();

		foreach ( $this->listing->feed_query_list as $id => $feed_query )
		{
			$fq_list[] = $feed_query;
		}

		$feeds_queries = '<table>';

		for ( $fq = 0; $fq < $max_feeds_queries; ++$fq )
		{
			$selected_feed_id  = $fq < sizeof( $fq_list ) ? $fq_list[ $fq ]->feed_id  : -1;
			$selected_query_id = $fq < sizeof( $fq_list ) ? $fq_list[ $fq ]->query_id : -1;

			$feeds_queries .= "<tr>";
			$feeds_queries .= "<td align=\"left\" valign=\"top\">" . $this->get_option_list( 'listing_feed_' . $fq, $feeds, $selected_feed_id ) . "</td>";
			$feeds_queries .= "<td align=\"left\" valign=\"top\">" . $this->get_option_list( 'listing_query_' . $fq, $queries, $selected_query_id ) . "</td>";
			$feeds_queries .= "<td align=\"left\" valign=\"top\">" . ( $this->is_missing_feed_or_query( $fq_list[ $fq ] ) ? "<span style=\"color: red;\">Missing feed or query</span>" : "" ) . "</td>";
			$feeds_queries .= "</tr>\n";
		}

		$feeds_queries .= "</table>\n";

		return $feeds_queries;
	}

	private function is_missing_feed_or_query( $feed_query )
	{
		return ( $feed_query->feed_id < 1 && $feed_query->query_id >= 1 ) || ( $feed_query->feed_id >= 1 && $feed_query->query_id < 1 );
	}

	private function copy_array( $source )
	{
		$destination = array();

		foreach ( $source as $key => $value )
		{
			$destination[ $key ] = $value;
		}

		return $destination;
	}

	private function get_option_list( $name, $objects, $selected_id = -1 )
	{
		$list = '';

		$list = "<select name=\"" . $name . "\">\n";

		foreach ( $objects as $id => $object )
		{
			$list .= "<option value=\"" . $object->id . "\"" . ( $selected_id == $object->id ? " selected=\"selected\"" : "" ) . ">" . $object->title . "</option>\n";
		}

		$list .= "</select>\n";

		return $list;
	}
}

class Flexical_Admin_Confirm_Delete_Listing_View extends Flexical_Admin_Basic_Listing_View
{
	public function render_details( $response )
	{
		echo( "<h3>Are you sure you want to delete this listing?</h3>" );

		$renderer = new Flexical_Admin_Listing_Form_Renderer();
		$renderer->listing = $response->listing;
		$renderer->feeds = $response->feeds;
		$renderer->queries = $response->queries;
		$renderer->formats = $response->formats;
		$renderer->submit_button_text = "Delete Listing";
		$renderer->cancel_enabled = true;
		$renderer->mode = 'readonly';
		$renderer->request_type = 'delete_listing';
		$renderer->view = $this;

		$renderer->render();
	}
}

class Flexical_Admin_Edit_Listing_View extends Flexical_Admin_Basic_Listing_View
{
	public function get_messages( $response )
	{
		$messages = array();

		switch ( get_class( $response ) )
		{
			case 'Flexical_Admin_Listing_To_Update_Invalid_Response':

				if ( $response->operation != 'create' && $response->operation != 'update' )
				{
					throw new Exception( "Unknown operation: " . $response->operation );
				}

				$messages = array_merge( $messages, $this->get_invalid_listing_messages( $response->listing ) );
				break;
		}

		return $messages;
	}

	private function get_invalid_listing_messages( $listing )
	{
		$messages = array();

		if ( $listing->format_id == -1 )
		{
			$messages[] = new Flexical_Admin_Error_Message( "A format for this listing was not selected." );
		}

		$fq_error = false;

		foreach ( $listing->feed_query_list as $fq_id => $feed_query )
		{
			if ( $feed_query->feed_id < 1 || $feed_query->query_id < 1 )
			{
				$fq_error = true;
				break;
			}
		}

		if ( $fq_error )
		{
			$messages[] = new Flexical_Admin_Error_Message( "At least one feed/query pair is missing either a feed or query selection." );
		}

		if ( sizeof( $listing->feed_query_list ) == 0 )
		{
			$messages[] = new Flexical_Admin_Error_Message( "You must include at least one feed/query pair in this listing." );
		}

		return $messages;
	}

	public function render_details( $response )
	{
		echo( "<h3>Edit Listing</h3>" );

		$renderer = new Flexical_Admin_Listing_Form_Renderer();
		$renderer->listing = $response->listing;
		$renderer->feeds = $response->feeds;
		$renderer->queries = $response->queries;
		$renderer->formats = $response->formats;
		$renderer->submit_button_text = ( $response->operation == 'create' ) ? "Create Listing" : "Update Listing";
		$renderer->cancel_enabled = true;
		$renderer->show_id_enabled = ( $response->operation == 'create' ) ? false : true;
		$renderer->mode = 'readwrite';
		$renderer->request_type = ( $response->operation == 'create' ) ? 'create_listing' : 'update_listing';
		$renderer->view = $this;

		$renderer->render();
	}
}

class Flexical_Admin_Sort_Order extends Flexical_Model_Object
{
	public function __construct( $id, $title )
	{
		$this->id = $id;
		$this->title = $title;
	}
}

?>
